const std = @import("std");
const assert = std.debug.assert;
const net = @import("../net.zig");
const Ip = net.ip.Ip;

/// a UDP packet header (comes after an IP header).
pub const Udp = extern struct {
    sport: u16 align(1),
    dport: u16 align(1),
    /// length, including udp header, not including IP header
    len: u16 align(1),
    checksum: u16 align(1),

    comptime {
        assert(@alignOf(@This()) == 1);
        assert(@bitSizeOf(@This()) / 8 == @sizeOf(@This()));
    }

    pub const header_size = @sizeOf(@This());
    pub const packet_lenth = Ip.packet_lenth + header_size;
};

pub fn send(packet: []u8, len: usize, sport: u16, dst: u32, dport: u16) !void {
    const udp: *Udp = @ptrCast(packet[Ip.packet_lenth..]);
    udp.* = .{
        .sport = sport,
        .dport = dport,
        .len = @intCast(Udp.header_size + len),
        .checksum = 0,
    };
    net.swapAllFields(udp);

    try net.ip.send(packet, .udp, dst, Udp.header_size + len);
}
